{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 规范化和单位向量\n",
    "\n",
    "## 向量的长度\n",
    "\n",
    "向量的长度，也称为向量的模，是表示向量大小的一个量，它反映了向量在空间中的“长度”或“大小”。向量的长度可以通过其坐标计算得出，具体公式为：对于二维向量，其长度等于其横坐标和纵坐标的平方和的平方根；对于三维向量，其长度等于其在x、y、z三个方向上分量平方和的平方根\n",
    "\n",
    "表示为 -- 向量的模 -- $\\begin{Vmatrix} \\vec{v} \\end{Vmatrix} $\n",
    "\n",
    "## 单位向量\n",
    "\n",
    "单位向量是指模等于1的向量。由于是非零向量，单位向量具有确定的方向\n",
    "\n",
    "一个非零向量除以它的模，可得所需单位向量。设原来的向量是 $\\overrightarrow{AB}$\n",
    "，则与它方向相同的的单位向量 $\\widehat{u}$ = $\\overrightarrow{AB} \\over \\begin{Vmatrix}AB\\end{Vmatrix} $ = 1\n",
    "\n",
    "> $\\frac{\\overrightarrow{AB}}{\\begin{Vmatrix}AB\\end{Vmatrix}}$\n",
    "\n",
    "单位向量有无数个 -- 以1个半径的圆\n",
    "\n",
    "### 标准单位向量\n",
    "\n",
    "二维的两个特殊的单位向量\n",
    "\n",
    "1. $\\overrightarrow{e_1}$ = $\\begin{pmatrix}1 & 0\\end{pmatrix}$\n",
    "2. $\\overrightarrow{e_2}$ = $\\begin{pmatrix}0 & 1\\end{pmatrix}$\n",
    "\n",
    "三维\n",
    "\n",
    "1. $\\overrightarrow{e_1}$ = $\\begin{pmatrix}1 & 0 & 0\\end{pmatrix}$\n",
    "2. $\\overrightarrow{e_2}$ = $\\begin{pmatrix}0 & 1 & 0\\end{pmatrix}$\n",
    "3. $\\overrightarrow{e_3}$ = $\\begin{pmatrix}0 & 0 & 1\\end{pmatrix}$\n",
    "\n",
    "```python\n",
    "def norm(self):\n",
    "    \"\"\"求模运算\"\"\"\n",
    "    return math.sqrt(sum(e**2 for e in self))\n",
    "\n",
    "def normalize(self):\n",
    "    \"\"\"求单位向量\"\"\"\n",
    "    if self.norm() <= EPSILON:  # 浮点比较0 epsilon代表一个极小值 1e-8\n",
    "        raise ZeroDivisionError(\"Normalize error!! norm is zero\")\n",
    "    # return Vector([[e / self.norm() for e in self]])\n",
    "    # return 1 / self.norm() * Vector(self)\n",
    "    return Vector(self) / self.norm()\n",
    "\n",
    "def __truediv__(self, k):\n",
    "    \"\"\"返回数量除法\"\"\"\n",
    "    return self * (1 / k)\n",
    "```\n",
    "\n",
    "EPSILON -- $\\epsilon $\n",
    "\n",
    "## 向量的点乘与几何意义\n",
    "\n",
    "\n",
    "### 向量的点乘\n",
    "\n",
    "点乘又称为点积,内积,数量积或者标量积。(**它的结果是一个数、一个标量**)\n",
    "\n",
    "$\\vec{u} \\cdot \\vec{v}$ = $\\begin{pmatrix} u_1 \\\\ u_2 \\\\ u_3 \\\\ ... \\\\u_n\\end{pmatrix} \\cdot \\begin{pmatrix} v_1 \\\\ v_2 \\\\ v_3 \\\\ ... \\\\v_n\\end{pmatrix}$ = $sum( \\begin{pmatrix} v_1 \\cdot u_1 \\\\ v_2 \\cdot u_2 \\\\ v_3 \\cdot u_3\\\\ ... \\\\v_n \\cdot u_n\\end{pmatrix})$ = $v_1 \\cdot u_1 + v_2 \\cdot u_2 + v_3 \\cdot u_3 + ... + v_n \\cdot u_n$ = $\\begin{Vmatrix} \\overrightarrow{u} \\end{Vmatrix} \\cdot \\begin{Vmatrix} \\overrightarrow{v} \\end{Vmatrix}\\cdot\\cos\\theta$\n",
    "\n",
    "推导\n",
    "\n",
    "余弦定理\n",
    "\n",
    "$a^2=b^2+c^2−2bc\\cdot\\cos\\theta\\Rightarrow$\n",
    "$\\begin{Vmatrix}\\overrightarrow{u} - \\overrightarrow{v}\\end{Vmatrix}^2 = \\begin{Vmatrix}\\overrightarrow{u}\\end{Vmatrix}^2 + \\begin{Vmatrix}\\overrightarrow{v}\\end{Vmatrix}^2 - 2 \\cdot \\begin{Vmatrix}\\overrightarrow{u}\\end{Vmatrix} \\cdot \\begin{Vmatrix}\\overrightarrow{v}\\end{Vmatrix} \\cdot\\cos\\theta \\Rightarrow$\n",
    "$\\begin{Vmatrix}\\overrightarrow{u}\\end{Vmatrix} \\cdot \\begin{Vmatrix}\\overrightarrow{v}\\end{Vmatrix} \\cdot \\cos\\theta = \\frac{1}{2}( \\begin{Vmatrix}\\overrightarrow{u}\\end{Vmatrix}^2 + \\begin{Vmatrix}\\overrightarrow{v}\\end{Vmatrix}^2 - \\begin{Vmatrix}\\overrightarrow{u} - \\overrightarrow{v}\\end{Vmatrix}^2 )$ = $\\frac{1}{2}\\begin{pmatrix}x_1^2 + y_1^2 + x_2^2 + y_2^2 - (x_1-x_2)^2 - (y_1 - y_2)^2 \\end{pmatrix}$ = $x_1x_2 + y_1y_2$\n",
    "\n",
    "\n",
    "### 点乘实现\n",
    "\n",
    "```python\n",
    "def dot(self, other):\n",
    "    \"\"\"向量点乘\"\"\"\n",
    "    assert len(self) == len(other), \"error is subtract, length of vector must be same\"\n",
    "    return sum(a * b for a, b in zip(self, other))\n",
    "```\n",
    "\n",
    "### 点乘的几何意义\n",
    "\n",
    "1. 计算$\\theta$ -- 如果为0,则向量必垂直\n",
    "2. 推荐系统 -- 点乘值越大,则越相似\n",
    "3. 投影计算\n",
    "   1. d=$\\begin{Vmatrix}\\vec v\\end{Vmatrix} \\cos\\theta$ = $\\frac{\\vec{u} \\cdot \\vec{v}}{\\begin{Vmatrix}\\vec u\\end{Vmatrix}}$\n",
    "   2. 投影点方向 -- $\\widehat{u}$ -- u的单位向量\n",
    "   3. 投影点坐标 $P_v = d \\cdot \\widehat{u}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def norm(self):\n",
    "    \"\"\"求模运算\"\"\"\n",
    "    return math.sqrt(sum(e**2 for e in self))\n",
    "\n",
    "def normalize(self):\n",
    "    \"\"\"求单位向量\"\"\"\n",
    "    if self.norm() <= EPSILON:  # 浮点比较0 epsilon代表一个极小值 1e-8\n",
    "        raise ZeroDivisionError(\"Normalize error!! norm is zero\")\n",
    "    # return Vector([[e / self.norm() for e in self]])\n",
    "    # return 1 / self.norm() * Vector(self)\n",
    "    return Vector(self) / self.norm()\n",
    "\n",
    "def __truediv__(self, k):\n",
    "    \"\"\"返回数量除法\"\"\"\n",
    "    return self * (1 / k)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def dot(self, other):\n",
    "    \"\"\"向量点乘\"\"\"\n",
    "    assert len(self) == len(other), \"error is subtract, length of vector must be same\"\n",
    "    return sum(a * b for a, b in zip(self, other))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
